package fun.ipconfig;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;

import fun.ipconfig.service.Handel;
import fun.ipconfig.service.Transformer;
class MyLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        if(!name.equals("fun.ipconfig.Transformer")){
            return super.loadClass(name);
        }
        try {
            Class<?> c = findLoadedClass(name);
            findLoadedClass(name);
            if (c != null) {
                return c;
            }
            byte[] classData = loadClassData(name);
            if (classData!= null) {
                return defineClass(name, classData, 0, classData.length);
            }
        } catch (Exception e) {
            throw new ClassNotFoundException();
        }
        return super.loadClass(name);
    }


    private byte[] loadClassData(String className) throws IOException {
        // 类加载路径加载代理类
        String path = MyLoader.class.getResource("").getPath() + "/" +  "Transformer.class";
        FileInputStream fis = new FileInputStream(path);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int length;
        while ((length = fis.read(buffer))!= -1) {
            bos.write(buffer, 0, length);
        }
        return bos.toByteArray();
    }
}

/**
 * 入口类
 * author gtinlian
 */
public class Agent {

    @SuppressWarnings("all")
    public static void premain(String agentArgs, Instrumentation inst){
        Handel.setIns(inst);
        System.out.println("                \033[32m热加载Agent启动\033[0m");
        if(agentArgs == null ){
            System.out.println("                \033[31m默认热加载包fun\033[0m");
            System.out.println("\033[33m 自定义热加载包[fun.ipconfig.service]:"+
            "\n\t启动时添加参数,默认热加载: -javaagent:agent-1.0-SNAPSHOT-jar-with-dependencies.jar\033[0m"+
            "\n\t"+
            "\033[31m启动时添加参数, 针对 pakcage包热加载 -javaagent:agent-1.0-SNAPSHOT-jar-with-dependencies.jar=package\033[0m"
            );
        }else{
            System.out.println("\033[32m加载包: "+ agentArgs+"\033[0m");
        }
        try{
            MyLoader myLoader = new MyLoader();
            Class transformer = myLoader.loadClass("fun.ipconfig.Transformer");
            ClassFileTransformer instance = (ClassFileTransformer)transformer
                .getConstructor(String.class)
                .newInstance(agentArgs == null ? "fun" : agentArgs);
                try{
                    transformer.getMethod("setIns", Instrumentation.class).invoke(instance, inst);
                }catch(Exception e){
                    System.out.println("            \033[32m未定义setIns方法, 可以定义setIns 获取 Instrumentation 实例\033[0m");
                }
            return;
        }catch(Exception e){
            System.out.println("未加载自定义ClassFileTransformer, 使用默认的Transformer启动");
        }
        // 没有参数默认加载所有包
        Transformer transformer = new Transformer(agentArgs);
        inst.addTransformer(transformer);
    }
    public static void agentmain(String agetnArgs, Instrumentation inst){
        premain(agetnArgs, inst);
    }
}
